% Server of the game, awaits for a connection to be made and starts a game.

:- include('main.pl').

:-use_module(library(sockets)).

port(60001).

server:-
        port(Port),
        write('Server initiating at port: '), write(Port), nl,
        socket_server_open(Port,Socket),
        socket_server_accept(Socket, Client, Stream, [type(text)]),
        write('Client '), write(Client), write(' has connected'), nl,
        server_loop(Stream, Client),
        socket_server_close(Socket),
        write('Server Exit'),nl.
        
server_loop(Stream, Client) :-
        repeat,
                read(Stream, ClientRequest),
                write('Received: "'), write(ClientRequest), write('" from: '), write(Client), nl,
                server_input(ClientRequest, ServerReply),
                format(Stream, '~q.~n', [ServerReply]),
                write('Send: '), write(ServerReply), nl,
                flush_output(Stream),
        (ClientRequest == bye; ClientRequest == end_of_file), !.

server_input(initialize, ok(Board)):-
        board(Board), !.
server_input(execute(Mov, Board), ok(NewBoard)):-
        valid_move(Mov, Board),
        execute_move(Mov, Board, NewBoard), !.
server_input(calculate(Level, J, Board), ok(Mov, NewBoard)):-
        calculate_move(Level, J, Board, Mov),
        execute_move(Mov, Board, NewBoard), !.
server_input(game_end(Board), ok(Winner)):-
        end_game(Board, Winner), !.
server_input(bye, ok):-!.
server_input(end_of_file, ok):-!.
server_input(_, invalid) :- !.

board(_).
valid_move(Mov, Board).
execute_move(Mov, Board, NewBoard).
calculate_move(Level, J, Board, Mov).
end_game(Board, Winner).